#include "memoire.h"

void lecteur(sharedMem * player_mem, sharedMem * memory,
		sharedCounter* counterMem, int semaSetID) {

	/* on demande l'accès exclusif au compteur de processus lecteurs */
	semDown(semaSetID, MUTEX);

	counterMem->lecteurs = counterMem->lecteurs + 1;

	/* on est le premier à lire , il faut obtenir l'accès exclusif a la memoire */
	if (counterMem->lecteurs == 1)
		semDown(semaSetID, DB); /* on essaie l'accès exclusif à la memoire partagee */

	semUp(semaSetID, MUTEX); /* on libere la ressource (rc) */

	/* section critique recopier dans la structure player_mem */
	ecrireMemoire(memory, player_mem);

	/* on redemande l'accès exclusif au compteur de processus lecteurs */
	semDown(semaSetID, MUTEX);
	counterMem->lecteurs = counterMem->lecteurs - 1;
	/* on est le dernier à lire , il faut liberer la memoire */
	if (counterMem->lecteurs == 0)
		semUp(semaSetID, DB); /* on libère l'accès a la memoire partagee pour le redacteur*/

	semUp(semaSetID, MUTEX);
}


void afficherMemoire(sharedMem * memory) {
	int i, j;
	printf("%d joueurs connecte(s)\n", memory->joueurs);

	printf("Pions visibles \n");
	for (i = 0; i < MAX_PIONS_PAR_JOUEUR; i++) {
		printf("%2d : ", memory->visible[i]);
	}

	for (i = 0; i < MAX_JOUEURS; i++) {
		printf("\nNom: %s, Prenom: %s \n", memory->nom[i],
				memory->prenom[i]);
		for (j = 0; j < MAX_PIONS_PAR_JOUEUR; j++) {
			printf("%2d : ", memory->trouver[i][j]);
		}
	}

	printf("\nRepartition\n");

	for (i = 0; i < DIFF_CONFIG; i++) {
		printf("Pour %d joueurs\n", i + 2);
		for (j = 0; j < DIFF_REPARTITION; j++) {
			printf("%d : ", memory->repartition[i][j]);
		}
		printf("\n");
	}
}

void ecrireMemoire(sharedMem * serv_mem, sharedMem * memory) {
	int i, j;

	memory->joueurs = serv_mem->joueurs;

	for (i = 0; i < MAX_PIONS_PAR_JOUEUR; i++) {
		memory->visible[i] = serv_mem->visible[i];
	}

	for (i = 0; i < MAX_JOUEURS; i++) {
		strcpy(memory->nom[i], serv_mem->nom[i]);
		strcpy(memory->prenom[i], serv_mem->prenom[i]);
		for (j = 0; j < MAX_PIONS_PAR_JOUEUR; j++) {
			memory->trouver[i][j] = serv_mem->trouver[i][j];
		}
	}

	if (memory->repartition[VIDE][VIDE] == 0) {
		for (i = 0; i < DIFF_CONFIG; i++) {
			for (j = 0; j < DIFF_REPARTITION; j++) {
				memory->repartition[i][j] = serv_mem->repartition[i][j];
			}
		}
	}
}

/* utilise par le serveur */
void redacteur(sharedMem * serv_mem, sharedMem * memory, int semaSetID) {
	/* on va demander l'accès exclusif à la memoire */
	semDown(semaSetID, DB);
	/* section critique */
	/* on peut commencer à ecrire */
	ecrireMemoire(serv_mem, memory);

	/* afficherMemoire(memory); */
	/* il faut la liberer */

	semUp(semaSetID, DB);

}

int shmInit(key_t key, size_t size) {
	int shmid;

	/*  Creation du segment */
	SYSS(shmid = shmget(key, size, IPC_CREAT | 0666));
	return shmid;
}

char* shmAttach(int shmId, char * addr) {

	/* On attache l'adresse au segment de la memoire et on la renvoie */
	SYSM(addr = shmat(shmId, NULL, 0));
	return addr;
}
